const Student = require('../models/Student');
const { Op } = require('sequelize');
const Class = require('../models/Class');
const validate = require('validate.js');
const moment = require('moment');
const { pick } = require('../util/propertyHelper');
exports.addStudent = async function (stuObj) {
  // 在验证之前 只取 希望 得到的字段  避免传入 不该传的字段
  stuObj = pick(stuObj, 'name', 'birthday', 'sex', 'mobile', 'ClassId');
  console.log(stuObj);

  // 自定义拓展 classExits 班级id是否存在
  validate.validators.classExits = async function (value) {
    const c = await Class.findByPk(value);
    if (c) {
      return;
    }
    return 'is not exist';
  };

  const rule = {
    //验证规则
    name: {
      presence: {
        allowEmpty: false,
      },
      type: 'string',
      length: {
        minimum: 1,
        maximum: 10,
      },
    },
    birthday: {
      presence: {
        allowEmpty: false,
      },
      datetime: {
        dateOnly: true, // 只需要日期 不需要 秒等部分
        earliest: +moment.utc().subtract(100, 'y'), // 最早100年前// +moment.utc() 相当于 moment.utc().valueof()
        latest: +moment.utc().subtract(5, 'y'), // 最迟时间
      },
    },
    sex: {
      presence: true, // 字段必须存在（允许 false 值，因为布尔类型本身可为假）
      type: 'boolean',
    },
    mobile: {
      presence: {
        allowEmpty: false,
      },
      format: /1\d{10}/,
    },
    ClassId: {
      presence: true,
      numericality: {
        onlyInteger: true, // 纯整数字
        strict: false, // 严格的
      },
      classExits: true, /// 自定义拓展 也可以在  整体验证 通过之后 单独 去后面验证 这里使用 拓展
    },
  };
  // const result = validate.validate(stuObj, rule); // 同步验证  验证通过会 什么都不返回
  // 验证不通过 会返回错误信息 是一个 数组
  await validate.async(stuObj, rule); // 使用了 classExits 异步验证 必须使用 validate.async 异步认证
  // 验证通过了 什么不会做 相当于 promise 成功了 验证失败了 则reject错误
  // 失败了 外层的catch 可以捕捉到
  const ins = await Student.create(stuObj);
  return ins.toJSON();
};

exports.deleteStudent = async function (id) {
  return await Student.destroy({
    where: {
      id,
    },
  });
};

exports.updateStudent = async function (id, obj) {
  return await Student.update(obj, {
    where: {
      id,
    },
  });
};

exports.getStudentById = async function (id) {
  const result = await Student.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  return null;
};

exports.getStudents = async function (page = 1, limit = 10, sex = -1, name = '') {
  // const results = await Student.findAll({
  //   offset: (page - 1) * limit,
  //   limit: +limit,
  // });
  // const total = await Student.count()
  // const datas = JSON.parse(JSON.stringify(results));
  // return {
  //   total,
  //   datas
  // }
  const where = {};
  if (sex !== -1) {
    where.sex = !!sex;
  }
  if (name) {
    where.name = {
      [Op.like]: `%${name}%`,
    };
  }

  const result = await Student.findAndCountAll({
    attributes: ['id', 'name', 'sex', 'birthday'],
    where,
    include: [Class],
    offset: (page - 1) * limit,
    limit: +limit,
  });
  return {
    total: result.count,
    datas: JSON.parse(JSON.stringify(result.rows)),
  };
};
